package expression;

import java.util.ArrayList;

import memory.Memory;
import exceptions.ParseException;

class Multiply extends Expression {

	ArrayList<Expression> multipliers;
	ArrayList<Boolean> operations;

	private void tryToParseMultiplyer(String t) throws ParseException {
		if (t.length() == 0) {
			throw new ParseException("empty expression");
		}
		
		if (t.charAt(0) == '(') {
			if (t.length() < 2) {
				throw new ParseException(t + " is not valid expression");
			}
			multipliers.add(new Sum(t.substring(1, t.length() - 1), memory));
			return;
		}
		if (Memory.isCorrectVariableName(t)) {
			multipliers.add(new Variable(t, memory));
			return;
		}
		try {
			multipliers.add(new Constant(Integer.parseInt(t), memory));
			return;
		} catch (NumberFormatException e) {
			throw new ParseException(t + " is not valid expression");
		}
	}

	public Multiply(String exp, Memory memory) throws ParseException {
		super(memory);
		multipliers = new ArrayList<Expression>();
		operations = new ArrayList<Boolean>();
		int n = exp.length();
		int cnt = 0;
		int last = 0;
		operations.add(true);
		for (int i = 0; i < n; i++) {
			if (exp.charAt(i) == '(') {
				cnt++;
			}
			if (exp.charAt(i) == ')') {
				cnt--;
			}
			if (cnt != 0) {
				continue;
			}
			if (exp.charAt(i) == '*' || exp.charAt(i) == '/') {
				if (i == n - 1) {
					throw new ParseException(exp + " is not valid variable");
				}
				if (last == i) {
					throw new ParseException("");
				}
				if (exp.charAt(i) == '*')
					operations.add(true);
				else
					operations.add(false);
				String t = exp.substring(last, i);
				last = i + 1;
				tryToParseMultiplyer(t);
			}
		}
		String t = exp.substring(last, n);
		tryToParseMultiplyer(t);
	}

	@Override
	public int calculate() {
		int x = 1;
		for (int i = 0; i < multipliers.size(); i++) {
			if (operations.get(i)) {
				x = x * multipliers.get(i).calculate();
			} else {
				x = x / multipliers.get(i).calculate();
			}
		}
		return x;
	}

}